(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('babel-runtime/helpers/extends'), require('babel-runtime/core-js/object/keys'), require('babel-runtime/helpers/objectWithoutProperties'), require('babel-runtime/helpers/classCallCheck'), require('babel-runtime/helpers/createClass'), require('babel-runtime/core-js/json/stringify'), require('watch-route')) :
    typeof define === 'function' && define.amd ? define(['babel-runtime/helpers/extends', 'babel-runtime/core-js/object/keys', 'babel-runtime/helpers/objectWithoutProperties', 'babel-runtime/helpers/classCallCheck', 'babel-runtime/helpers/createClass', 'babel-runtime/core-js/json/stringify', 'watch-route'], factory) :
    (global.stat = factory(global._extends,global._Object$keys,global._objectWithoutProperties,global._classCallCheck,global._createClass,global._JSON$stringify,global.WatchRoute));
}(this, (function (_extends,_Object$keys,_objectWithoutProperties,_classCallCheck,_createClass,_JSON$stringify,WatchRoute) { 'use strict';

    _extends = _extends && _extends.hasOwnProperty('default') ? _extends['default'] : _extends;
    _Object$keys = _Object$keys && _Object$keys.hasOwnProperty('default') ? _Object$keys['default'] : _Object$keys;
    _objectWithoutProperties = _objectWithoutProperties && _objectWithoutProperties.hasOwnProperty('default') ? _objectWithoutProperties['default'] : _objectWithoutProperties;
    _classCallCheck = _classCallCheck && _classCallCheck.hasOwnProperty('default') ? _classCallCheck['default'] : _classCallCheck;
    _createClass = _createClass && _createClass.hasOwnProperty('default') ? _createClass['default'] : _createClass;
    _JSON$stringify = _JSON$stringify && _JSON$stringify.hasOwnProperty('default') ? _JSON$stringify['default'] : _JSON$stringify;
    WatchRoute = WatchRoute && WatchRoute.hasOwnProperty('default') ? WatchRoute['default'] : WatchRoute;

    if (!Array.prototype.fill) {
        Object.defineProperty(Array.prototype, 'fill', {
            value: function value(_value) {
                if (this == null) {
                    throw new TypeError('this is null or not defined');
                }

                var O = Object(this);

                var len = O.length >>> 0;

                var start = arguments[1];
                var relativeStart = start >> 0;

                var k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len);

                var end = arguments[2];
                var relativeEnd = end === undefined ? len : end >> 0;

                var final = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len);

                while (k < final) {
                    O[k] = _value;
                    k++;
                }

                return O;
            }
        });
    }

    if (!Array.prototype.find) {
        Object.defineProperty(Array.prototype, 'find', {
            value: function value(predicate) {
                if (this == null) {
                    throw new TypeError('"this" is null or not defined');
                }

                var o = Object(this);

                var len = o.length >>> 0;

                if (typeof predicate !== 'function') {
                    throw new TypeError('predicate must be a function');
                }

                var thisArg = arguments[1];

                var k = 0;

                while (k < len) {
                    var kValue = o[k];
                    if (predicate.call(thisArg, kValue, k, o)) {
                        return kValue;
                    }

                    k++;
                }

                return undefined;
            }
        });
    }

    if (!Array.prototype.filter) {
        Array.prototype.filter = function (fun) {

            if (this === void 0 || this === null) throw new TypeError();

            var t = Object(this);
            var len = t.length >>> 0;
            if (typeof fun !== 'function') throw new TypeError();

            var res = [];
            var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
            for (var i = 0; i < len; i++) {
                if (i in t) {
                    var val = t[i];

                    if (fun.call(thisArg, val, i, t)) res.push(val);
                }
            }

            return res;
        };
    }

    if (!Array.prototype.findIndex) {
        Object.defineProperty(Array.prototype, 'findIndex', {
            value: function value(predicate) {
                if (this == null) {
                    throw new TypeError('"this" is null or not defined');
                }

                var o = Object(this);

                var len = o.length >>> 0;

                if (typeof predicate !== 'function') {
                    throw new TypeError('predicate must be a function');
                }

                var thisArg = arguments[1];

                var k = 0;

                while (k < len) {
                    var kValue = o[k];
                    if (predicate.call(thisArg, kValue, k, o)) {
                        return k;
                    }

                    k++;
                }

                return -1;
            }
        });
    }

    if (!Array.prototype.reduce) {
        Object.defineProperty(Array.prototype, 'reduce', {
            value: function value(callback) {
                if (this === null) {
                    throw new TypeError('Array.prototype.reduce ' + 'called on null or undefined');
                }
                if (typeof callback !== 'function') {
                    throw new TypeError(callback + ' is not a function');
                }

                var o = Object(this);

                var len = o.length >>> 0;

                var k = 0;
                var value;

                if (arguments.length >= 2) {
                    value = arguments[1];
                } else {
                    while (k < len && !(k in o)) {
                        k++;
                    }

                    if (k >= len) {
                        throw new TypeError('Reduce of empty array ' + 'with no initial value');
                    }
                    value = o[k++];
                }

                while (k < len) {
                    if (k in o) {
                        value = callback(value, o[k], k, o);
                    }

                    k++;
                }

                return value;
            }
        });
    }

    var version = "3.1.2";

    var GT = function GT(key) {
    	return window.sessionStorage.getItem(key);
    };
    var ST = function ST(key, value) {
    	return window.sessionStorage.setItem(key, value);
    };

    var GT_O = function GT_O(key) {
    	return JSON.parse(GT(key) || '{}');
    };
    var ST_O = function ST_O(key, value) {
    	return ST(key, _JSON$stringify(value));
    };

    var getPageReport = function getPageReport() {
    	return GT_O('SXYJ_STAT_PAGE');
    };
    var setPageReport = function setPageReport(value) {
    	return ST_O('SXYJ_STAT_PAGE', value);
    };

    var getNodeReport = function getNodeReport(path) {
    	return GT_O('SXYJ_STAT_NODE' + '-' + path);
    };
    var setNodeReport = function setNodeReport(path, value) {
    	return ST_O('SXYJ_STAT_NODE' + '-' + path, value);
    };

    var Stat = function () {
    	function Stat(report) {
    		var _this = this;

    		var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
    		    _ref$chainLength = _ref.chainLength,
    		    chainLength = _ref$chainLength === undefined ? 6 : _ref$chainLength,
    		    _ref$oncePageView = _ref.oncePageView,
    		    oncePageView = _ref$oncePageView === undefined ? true : _ref$oncePageView,
    		    _ref$onceNodeView = _ref.onceNodeView,
    		    onceNodeView = _ref$onceNodeView === undefined ? true : _ref$onceNodeView,
    		    _ref$startCallback = _ref.startCallback,
    		    startCallback = _ref$startCallback === undefined ? null : _ref$startCallback;

    		_classCallCheck(this, Stat);

    		this._options = {
    			chainLength: chainLength,
    			oncePageView: oncePageView,
    			onceNodeView: onceNodeView,

    			DOM_toKey: '',
    			DOM_fromKey: ''
    		};

    		this._report = function (data, options) {
    			return Array.isArray(data) ? _this.options.report(data, options) : _this.options.report([data], options);
    		};

    		this._route = new WatchRoute({ chainLength: chainLength, getLastPageDetail: true, startCallback: startCallback });

    		this._currentKey = '__DEFAULT_KEY__';

    		this._domNodeList = {};

    		this._domClickList = {};

    		this._cachePage = [];

    		this._cacheNode = [];

    		this._pageReportHistory = getPageReport();

    		this._nodeReportHistory = {};

    		this.options = {
    			report: report,

    			stopPageReport: false,

    			cachePageReport: report ? false : true,

    			stopRouteReport: false,

    			baseDataDefault: {},

    			otherDataDefault: {},

    			reportPathname: ''
    		};

    		this.init();
    	}

    	_createClass(Stat, [{
    		key: 'setReport',
    		value: function setReport(report) {
    			var _this2 = this;

    			if (typeof report !== 'function') return;

    			this.options.report = report;

    			this.options.cachePageReport = false;
    			this.getCachePage().forEach(function (item) {
    				return _this2._report(item);
    			});
    			this.getCacheNode().forEach(function (item) {
    				return _this2._report(item);
    			});
    		}
    	}, {
    		key: 'bindDom',
    		value: function bindDom(el) {
    			var _this3 = this;

    			var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

    			var _ref2$id = _ref2.id,
    			    id = _ref2$id === undefined ? '' : _ref2$id,
    			    _ref2$unBind = _ref2.unBind,
    			    unBind = _ref2$unBind === undefined ? false : _ref2$unBind,
    			    _ref2$unClick = _ref2.unClick,
    			    unClick = _ref2$unClick === undefined ? false : _ref2$unClick,
    			    params = _objectWithoutProperties(_ref2, ['id', 'unBind', 'unClick']);

    			var path = arguments[2];

    			if (!id || unBind) return;
    			var key = path || this._currentKey;

    			if (!this._domNodeList[key]) {
    				this._domNodeList[key] = {};
    				this._domClickList[key] = {};
    			}

    			this._domNodeList[key][id] = { el: el, params: params };

    			if (!unClick) {
    				if (this._domClickList[key][id]) el.removeEventListener('click', this._domClickList[key][id]);

    				this._domClickList[key][id] = function (e) {
    					return _this3.clickReport(params);
    				};
    				el.addEventListener('click', this._domClickList[key][id]);
    			}
    		}
    	}, {
    		key: 'removeBind',
    		value: function removeBind(el) {
    			var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
    			    _ref3$id = _ref3.id,
    			    id = _ref3$id === undefined ? '' : _ref3$id,
    			    _ref3$unBind = _ref3.unBind,
    			    unBind = _ref3$unBind === undefined ? false : _ref3$unBind,
    			    _ref3$unClick = _ref3.unClick,
    			    unClick = _ref3$unClick === undefined ? false : _ref3$unClick;

    			if (!id || unBind) return;
    			var key = this._currentKey;

    			!unClick && el.removeEventListener('click', this._domClickList[key][id]);
    			delete this._domClickList[key][id];
    			delete this._domNodeList[key][id];
    		}
    	}, {
    		key: 'getCachePage',
    		value: function getCachePage() {
    			var from = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
    			var to = arguments[1];


    			return this._cachePage.splice(from, this._cachePage.slice(from, to).length);
    		}
    	}, {
    		key: 'getCacheNode',
    		value: function getCacheNode() {
    			var from = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
    			var to = arguments[1];


    			return this._cacheNode.splice(from, this._cacheNode.slice(from, to).length);
    		}
    	}, {
    		key: 'clickReport',
    		value: function clickReport(params) {
    			var other = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

    			return this._report(this._getNodeClickData(params), other);
    		}
    	}, {
    		key: 'viewReport',
    		value: function viewReport(params) {
    			var _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

    			var _ref4$pathname = _ref4.pathname,
    			    pathname = _ref4$pathname === undefined ? this.options.reportPathname || this._route.currentPage.pathname + this._route.currentPage.search : _ref4$pathname,
    			    _ref4$target = _ref4.target,
    			    target = _ref4$target === undefined ? 'page' : _ref4$target,
    			    other = _objectWithoutProperties(_ref4, ['pathname', 'target']);

    			if (this.options.stopPageReport) return;

    			switch (target) {
    				case 'page':
    					if (this.options.cachePageReport) return this._cachePage.push(this._getPageViewData(params));

    					if (this._options.oncePageView) {
    						if (this._pageReportHistory[pathname]) return;
    						this._pageReportHistory[pathname] = true;
    						setPageReport(this._pageReportHistory);
    					}

    					return this._report(this._getPageViewData(params), other);
    				case 'node':
    					if (this.options.cachePageReport) return this._cacheNode.push(this._getNodeViewData(params));

    					return this._report(this._getNodeViewData(params), other);

    				default:
    					return;
    			}
    		}
    	}, {
    		key: 'nodeReport',
    		value: function nodeReport() {
    			var _this4 = this;

    			var param = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

    			var key = this._currentKey;

    			if (!this._nodeReportHistory[key]) this._nodeReportHistory[key] = this._options.onceNodeView ? getNodeReport(key) : {};

    			var ids = _Object$keys(this._domNodeList[key] || {});
    			var _window = window,
    			    innerHeight = _window.innerHeight,
    			    innerWidth = _window.innerWidth;

    			var reportList = [];

    			ids.forEach(function (id) {
    				if (!_this4._domNodeList[key][id]) return;
    				if (_this4._nodeReportHistory[key][id]) return delete _this4._domNodeList[key][id];

    				var _domNodeList$key$id = _this4._domNodeList[key][id],
    				    el = _domNodeList$key$id.el,
    				    params = _domNodeList$key$id.params;

    				var _el$getBoundingClient = el.getBoundingClientRect(),
    				    left = _el$getBoundingClient.left,
    				    top = _el$getBoundingClient.top;

    				var offsetWidth = el.offsetWidth,
    				    offsetHeight = el.offsetHeight;


    				if (left >= 0 - offsetWidth / 3 * 2 && left <= innerWidth - offsetWidth / 3 && top >= 0 - offsetHeight / 3 * 2 && top <= innerHeight - offsetHeight / 3) {
    					reportList.push(params);
    					delete _this4._domNodeList[key][id];
    					_this4._nodeReportHistory[key][id] = true;
    				}
    			});

    			this._options.onceNodeView && setNodeReport(key, this._nodeReportHistory[key]);

    			reportList.length && this.viewReport(reportList, _extends({ target: 'node' }, param));
    		}
    	}, {
    		key: '_getBaseData',
    		value: function _getBaseData() {
    			var _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

    			var _ref5$type = _ref5.type,
    			    type = _ref5$type === undefined ? this.options.baseDataDefault.type || 'view' : _ref5$type,
    			    _ref5$target = _ref5.target,
    			    target = _ref5$target === undefined ? this.options.baseDataDefault.target || '页面' : _ref5$target,
    			    _ref5$page = _ref5.page,
    			    page = _ref5$page === undefined ? this.options.baseDataDefault.page || this._route.currentPage.href : _ref5$page,
    			    _ref5$parentPage = _ref5.parentPage,
    			    parentPage = _ref5$parentPage === undefined ? this.options.baseDataDefault.parentPage || this._route.parentPage.href || '' : _ref5$parentPage,
    			    _ref5$pageParams = _ref5.pageParams,
    			    pageParams = _ref5$pageParams === undefined ? this.options.baseDataDefault.pageParams || _extends({}, this._route.currentPage.query) : _ref5$pageParams,
    			    _ref5$parentParams = _ref5.parentParams,
    			    parentParams = _ref5$parentParams === undefined ? this.options.baseDataDefault.parentParams || _extends({}, this._route.parentPage.query) : _ref5$parentParams,
    			    _ref5$actionParams = _ref5.actionParams,
    			    actionParams = _ref5$actionParams === undefined ? this.options.baseDataDefault.actionParams || {} : _ref5$actionParams,
    			    other = _objectWithoutProperties(_ref5, ['type', 'target', 'page', 'parentPage', 'pageParams', 'parentParams', 'actionParams']);

    			var otherDataDefault = this.options.otherDataDefault;

    			var otherData = _extends({}, otherDataDefault);

    			_Object$keys(otherDataDefault).forEach(function (key) {
    				var value = typeof otherDataDefault[key] === 'function' ? otherDataDefault[key]() : otherDataDefault[key];
    				if (otherDataDefault[key] !== void 0) otherData[key] = value;
    			});

    			return {
    				version: version,

    				type: type,
    				target: target,
    				page: page,
    				parentPage: parentPage,
    				pageParams: pageParams,
    				parentParams: parentParams,
    				actionParams: actionParams,

    				pageDetail: {
    					pageStack: this._route.getOwnPageStack(),
    					chain: this._route.getOwnChain(),
    					time: Date.now() + '',
    					pageSize: window.innerWidth + 'x' + window.innerHeight,
    					title: window.document.title
    				},
    				other: _extends({}, other, otherData)
    			};
    		}
    	}, {
    		key: '_getPageViewData',
    		value: function _getPageViewData(params) {

    			return [this._getBaseData(_extends({
    				type: 'view'
    			}, params))];
    		}
    	}, {
    		key: '_getNodeClickData',
    		value: function _getNodeClickData(params) {

    			return [this._getBaseData(_extends({
    				type: 'click'
    			}, params))];
    		}
    	}, {
    		key: '_getNodeViewData',
    		value: function _getNodeViewData(params) {
    			var _this5 = this;

    			return params.map(function (item) {
    				return _this5._getBaseData(_extends({
    					type: 'view'
    				}, item));
    			});
    		}
    	}, {
    		key: 'init',
    		value: function init() {
    			var _this6 = this;

    			this._route.afterEach(function (route) {
    				var pathname = route.detail.pathname;
    				var toKey = _this6._currentKey = _this6._options.DOM_toKey || pathname.match(/^\/?[^\/?#]*/)[0];

    				var lastPathname = route.lastChainDetail.pathname || '';
    				var fromKey = _this6._options.DOM_fromKey || lastPathname.match(/^\/?[^\/?#]*/)[0];

    				if (toKey !== fromKey) {
    					if (!_this6._domNodeList[toKey]) {
    						_this6._domNodeList[toKey] = {};
    						_this6._domClickList[toKey] = {};
    					}

    					_this6._domNodeList[fromKey] = {};
    					_this6._domClickList[fromKey] = {};
    				}

    				if (!_this6._nodeReportHistory[toKey]) _this6._nodeReportHistory[toKey] = _this6._options.onceNodeView ? getNodeReport(toKey) : {};

    				if (_this6.options.stopRouteReport) return;

    				setTimeout(function () {
    					return _this6.viewReport({}, { pathname: pathname + route.detail.search });
    				}, 4);
    			});

    			var nodeTimer = void 0;

    			window.addEventListener('scroll', function (e) {
    				clearTimeout(nodeTimer);

    				nodeTimer = setTimeout(_this6.nodeReport.bind(_this6), 500);
    			});
    		}
    	}]);

    	return Stat;
    }();

    var stat = void 0;
    function core () {
    	for (var _len = arguments.length, arg = Array(_len), _key = 0; _key < _len; _key++) {
    		arg[_key] = arguments[_key];
    	}

    	return stat || (stat = new (Function.prototype.bind.apply(Stat, [null].concat(arg)))());
    }

    return core;

})));
